package com.codrim.cs.data.server.dao.mapper;

import com.codrim.cs.data.rpc.dto.param.AffiliateReportParamDTO;
import com.codrim.cs.data.rpc.dto.param.OfferReportField;
import com.codrim.cs.data.rpc.enums.OrderBy;
import com.codrim.cs.data.server.dao.param.OrderByColumn;
import com.codrim.cs.data.server.dao.param.SelectColumnNameAndAlias;

import java.util.Arrays;
import java.util.Optional;

/**
 * @author Liang.Zhuge
 * @date 08/02/2018
 */
public enum AffiliateMergeColumnAndAlias {
    Sdate(AffiliateReportParamDTO.AffiliateOfferReportField.Sdate, "sdate", "sdates"),
    Advertiser(AffiliateReportParamDTO.AffiliateOfferReportField.Advertiser, "advertiser_id", "advertiserId"),
    AffAdvertiserManager(AffiliateReportParamDTO.AffiliateOfferReportField.AffAdvertiserManager, "aff_advertiser_manager_id", "affAdvertiserManagerId"),
    Offer(AffiliateReportParamDTO.AffiliateOfferReportField.Offer, "offer_id", "offerId"),
    AffiliateSource(AffiliateReportParamDTO.AffiliateOfferReportField.AffiliateSource, "sorce_id", "sourceId"),
    Sub1(AffiliateReportParamDTO.AffiliateOfferReportField.Sub1, "sub1", "sub1"),
    Sub2(AffiliateReportParamDTO.AffiliateOfferReportField.Sub2, "sub2", "sub2"),
    Sub3(AffiliateReportParamDTO.AffiliateOfferReportField.Sub3, "sub3", "sub3"),
    Sub4(AffiliateReportParamDTO.AffiliateOfferReportField.Sub4, "sub4", "sub4"),
    Sub5(AffiliateReportParamDTO.AffiliateOfferReportField.Sub5, "sub5", "sub5"),
    Clicks(AffiliateReportParamDTO.AffiliateOfferReportField.Clicks, "sum(click)", "clicks"),
    UniqueClicks(AffiliateReportParamDTO.AffiliateOfferReportField.UniqueClicks, "sum(uclick)", "uniqueClicks"),
    GrossConversions(AffiliateReportParamDTO.AffiliateOfferReportField.GrossConversions, "sum(gc)", "grossConversions"),
    Revenue(AffiliateReportParamDTO.AffiliateOfferReportField.Revenue, "sum(aprice)", "revenue"),
    Cost(AffiliateReportParamDTO.AffiliateOfferReportField.Cost, "sum(pprice)", "cost"),
    Conversions(AffiliateReportParamDTO.AffiliateOfferReportField.Conversions, "sum(conversion)", "conversions"),
    ScrubbedConversions(AffiliateReportParamDTO.AffiliateOfferReportField.ScrubbedConversions, "sum(sc)", "scrubbedConversions"),
    Caps(AffiliateReportParamDTO.AffiliateOfferReportField.Caps, "sum(caps)", "caps"),;

    private final AffiliateReportParamDTO.AffiliateOfferReportField field;
    private final SelectColumnNameAndAlias selectColumnNameAndAlias;

    public static SelectColumnNameAndAlias select(OfferReportField field) {
        if (field == null || !field.isSelect()) {
            return null;
        }
        Optional<AffiliateMergeColumnAndAlias> first = Arrays.stream(AffiliateMergeColumnAndAlias.values())
                .filter(item -> item.field == field.getField())
                .findFirst();
        return first.isPresent() ? first.get().selectColumnNameAndAlias : null;
    }

    public static String groupBy(OfferReportField field) {
        if (field == null) {
            return null;
        }
        Optional<AffiliateMergeColumnAndAlias> first = Arrays.stream(AffiliateMergeColumnAndAlias.values())
                .filter(item -> field.isGroupBy() && item.field == field.getField())
                .findFirst();
        return first.isPresent() ? first.get().selectColumnNameAndAlias.columnName : null;
    }

    public static OrderByColumn orderBy(OfferReportField field) {
        if (field == null) {
            return null;
        }
        return Arrays.stream(AffiliateMergeColumnAndAlias.values())
                .filter(item -> field.getOrderBy().getKey() != OrderBy.IGNORE && item.field == field.getField())
                .findFirst()
                .map(affiliateMergeColumnAndAlias -> new OrderByColumn(affiliateMergeColumnAndAlias.selectColumnNameAndAlias.alias, field.getOrderBy().getDesc()))
                .orElse(null);
    }

    AffiliateMergeColumnAndAlias(AffiliateReportParamDTO.AffiliateOfferReportField field, String columnName, String alias) {
        this.field = field;
        this.selectColumnNameAndAlias = new SelectColumnNameAndAlias(columnName, alias);
    }

    public SelectColumnNameAndAlias getSelectColumnNameAndAlias() {
        return this.selectColumnNameAndAlias;
    }
}
